package org.sgx.jsutil.client;

import com.google.gwt.core.client.JavaScriptObject;

/**
 * I represent any JavaScript value this is any value of type number, boolean, string, object, array, null.
 * 
 * This GWT Implementation for such utility use a javascript object wrapper and the java user must ask for the java value 
 * type (int, String, boolean, JavaScriptObject) explicitly. As a consequence this imply a little overhead. 
 * 
 * @author sg
 * 
 */
public class JSValue extends JavaScriptObject {
	protected JSValue(){}
	public static final String TYPE_STRING = "string", TYPE_BOOLEAN = "boolean", TYPE_NUMBER = "number",
			TYPE_OBJ = "object";

	
	//TODO: make creators like the following also for arrays. 
	public static final native JSValue create(double i)/*-{
		return {
			"value" : i,
			"type" : "number"
		};
	}-*/;

	public static final native JSValue create(int i)/*-{
		return {
			"value" : i,
			"type" : "number"
		};
	}-*/;

	public static final native JSValue create(String i)/*-{
		return {
			"value" : i,
			"type" : "string"
		};
	}-*/;

	public static final native JSValue create(boolean i)/*-{
		return {
			"value" : i,
			"type" : "boolean"
		};
	}-*/;

	public static final native JSValue create(JavaScriptObject i)/*-{
		return {
			"value" : i,
			"type" : "object"
		};
	}-*/;

	public final native String asString()/*-{
		return this.value ? this.value + "" : null;
	}-*/;

	public final native boolean asBoolean()/*-{
		return this.value || false;
	}-*/;

	public final native JavaScriptObject asObject()/*-{
		return this.value;
	}-*/;

	public final native double asDouble()/*-{
		return this.value;
	}-*/;

	public final native int asInteger()/*-{
		return this.value;
	}-*/;

	/**
	 * this object types - one of TYPE_* constants
	 * 
	 * @return
	 */
	public native final String type() /*-{
		return this["type"];
	}-*/;

	/**
	 * this object types - one of TYPE_* constants
	 * 
	 * @param val
	 * @return this - for setter chaining
	 */
	public native final JSValue type(String val) /*-{
		this["type"] = val;
		return this;
	}-*/;

}
